<template>
    <div class="container">
      <h1>自定义下拉框组件</h1>
      <!-- cces  aasd 123123 ss-->
       <!-- 123123123123 -->
        <!-- 213123123123 -->
         <!-- tetetetetet -->
      <!-- 基础单选下拉框 -->
      <div class="section">
        <h2>基础单选</h2>
        <custom-select
          v-model="selectedValue"
          :options="options"
          placeholder="请选择"
        ></custom-select>
        <p>选中值: {{ selectedValue }}</p>
      </div>
      
      <!-- 多选下拉框 -->
      <div class="section">
        <h2>多选</h2>
        <custom-select
          v-model="multiSelected"
          :options="options"
          multiple
          placeholder="请选择多个选项"
        ></custom-select>
        <p>选中值: {{ multiSelected }}</p>
      </div>
      
      <!-- 远程搜索下拉框 -->
      <div class="section">
        <h2>远程搜索</h2>
        <custom-select
          v-model="remoteSelected"
          :options="remoteOptions"
          filterable
          remote
          :remote-method="remoteSearch"
          placeholder="输入关键字搜索"
          loading-text="搜索中..."
          no-match-text="无匹配数据"
          no-data-text="无数据"
        ></custom-select>
        <p>选中值: {{ remoteSelected }}</p>
      </div>
      
      <!-- 自定义模板下拉框 -->
      <div class="section">
        <h2>自定义选项模板</h2>
        <custom-select
          v-model="templateSelected"
          :options="templateOptions"
          placeholder="选择用户"
        >
          <template #option="{ option }">
            <div class="custom-option">
              <img :src="option.avatar" class="avatar" />
              <div class="info">
                <span class="name">{{ option.name }}</span>
                <span class="email">{{ option.email }}</span>
              </div>
            </div>
          </template>
        </custom-select>
        <p>选中用户: {{ templateSelected }}</p>
      </div>
      
      <!-- 可清空和禁用 -->
      <div class="section">
        <h2>可清空和禁用</h2>
        <div class="controls">
          <button @click="clearAll">清空所有选择</button>
          <button @click="disabled = !disabled">{{ disabled ? '启用' : '禁用' }}下拉框</button>
        </div>
        <custom-select
          v-model="clearableSelected"
          :options="options"
          clearable
          :disabled="disabled"
          placeholder="可清空的下拉框"
        ></custom-select>
        <p>选中值: {{ clearableSelected }}</p>
      </div>
    </div>
  </template>
  
  <script>
  // 自定义下拉框组件
  const CustomSelect = {
    name: 'CustomSelect',
    props: {
      value: [String, Number, Array], // 支持单选和多选
      options: {
        type: Array,
        default: () => []
      },
      placeholder: {
        type: String,
        default: '请选择'
      },
      multiple: Boolean, // 是否多选
      filterable: Boolean, // 是否可搜索
      remote: Boolean, // 是否远程搜索
      remoteMethod: Function, // 远程搜索方法
      loadingText: {
        type: String,
        default: '加载中...'
      },
      noMatchText: {
        type: String,
        default: '无匹配数据'
      },
      noDataText: {
        type: String,
        default: '无数据'
      },
      clearable: Boolean, // 是否可清空
      disabled: Boolean // 是否禁用
    },
    data() {
      return {
        isOpen: false,
        searchQuery: '',
        loading: false,
        filteredOptions: [],
        selectedLabel: '',
        selectedLabels: []
      };
    },
    computed: {
      // 合并选项和过滤后的选项
      mergedOptions() {
        if (this.filterable && this.searchQuery) {
          return this.filteredOptions.length ? this.filteredOptions : [];
        }
        return this.options;
      },
      // 是否显示无数据提示
      showNoData() {
        return this.mergedOptions.length === 0;
      },
      // 当前显示的值
      displayValue() {
        if (this.multiple) {
          return this.selectedLabels.length ? this.selectedLabels.join(', ') : this.placeholder;
        }
        return this.selectedLabel || this.placeholder;
      },
      // 是否显示清除按钮
      showClear() {
        return this.clearable && 
               ((this.multiple && this.value && this.value.length) || 
                (!this.multiple && this.value !== '' && this.value !== null && this.value !== undefined));
      }
    },
    watch: {
      options: {
        immediate: true,
        handler() {
          this.updateSelectedLabels();
        }
      },
      value: {
        immediate: true,
        handler() {
          this.updateSelectedLabels();
        }
      },
      searchQuery(newVal) {
        if (this.remote && this.remoteMethod) {
          this.loading = true;
          this.remoteMethod(newVal, (options) => {
            this.filteredOptions = options;
            this.loading = false;
          });
        } else if (this.filterable) {
          this.filterOptions(newVal);
        }
      }
    },
    methods: {
      // 更新选中的标签
      updateSelectedLabels() {
        if (this.multiple) {
          this.selectedLabels = [];
          if (Array.isArray(this.value)) {
            this.value.forEach(val => {
              const option = this.options.find(opt => opt.value === val);
              if (option) {
                this.selectedLabels.push(option.label);
              }
            });
          }
        } else {
          const option = this.options.find(opt => opt.value === this.value);
          this.selectedLabel = option ? option.label : '';
        }
      },
      // 过滤选项
      filterOptions(query) {
        if (!query) {
          this.filteredOptions = this.options;
          return;
        }
        this.filteredOptions = this.options.filter(option => {
          return option.label.toLowerCase().includes(query.toLowerCase());
        });
      },
      // 切换下拉框
      toggleDropdown() {
        if (this.disabled) return;
        this.isOpen = !this.isOpen;
        if (this.isOpen && this.filterable) {
          this.$nextTick(() => {
            this.$refs.searchInput.focus();
          });
        }
      },
      // 选择选项
      selectOption(option) {
        if (this.multiple) {
          const newValue = Array.isArray(this.value) ? [...this.value] : [];
          const index = newValue.indexOf(option.value);
          if (index === -1) {
            newValue.push(option.value);
          } else {
            newValue.splice(index, 1);
          }
          this.$emit('input', newValue);
        } else {
          this.$emit('input', option.value);
          this.isOpen = false;
        }
      },
      // 清除选择
      clearSelection() {
        this.$emit('input', this.multiple ? [] : null);
        this.isOpen = false;
      },
      // 判断是否选中
      isSelected(option) {
        if (this.multiple) {
          return Array.isArray(this.value) && this.value.includes(option.value);
        }
        return this.value === option.value;
      },
      // 点击外部关闭下拉框
      handleClickOutside(e) {
        if (!this.$el.contains(e.target)) {
          this.isOpen = false;
        }
      }
    },
    mounted() {
      document.addEventListener('click', this.handleClickOutside);
      if (this.filterable && !this.remote) {
        this.filteredOptions = this.options;
      }
    },
    beforeDestroy() {
      document.removeEventListener('click', this.handleClickOutside);
    },
    render(h) {
      const dropdownClasses = [
        'dropdown',
        {
          'is-open': this.isOpen,
          'is-disabled': this.disabled,
          'is-multiple': this.multiple
        }
      ];
  
      return (
        <div class={dropdownClasses}>
          <div class="dropdown-toggle" onClick={this.toggleDropdown}>
            <div class="dropdown-selection">
              {this.displayValue}
            </div>
            {this.showClear ? (
              <span class="dropdown-clear" onClick={(e) => {
                e.stopPropagation();
                this.clearSelection();
              }}>×</span>
            ) : (
              <span class="dropdown-arrow">▼</span>
            )}
          </div>
          
          {this.isOpen && (
            <div class="dropdown-menu">
              {this.filterable && (
                <div class="dropdown-search">
                  <input
                    ref="searchInput"
                    type="text"
                    class="search-input"
                    vModel={this.searchQuery}
                    placeholder="搜索..."
                  />
                </div>
              )}
              
              <ul class="dropdown-options">
                {this.loading ? (
                  <li class="dropdown-loading">{this.loadingText}</li>
                ) : this.showNoData ? (
                  <li class="dropdown-empty">{this.noDataText}</li>
                ) : (
                  this.mergedOptions.map(option => (
                    <li
                      class={[
                        'dropdown-option',
                        {
                          'is-selected': this.isSelected(option),
                          'is-disabled': option.disabled
                        }
                      ]}
                      onClick={() => !option.disabled && this.selectOption(option)}
                      key={option.value}
                    >
                      {this.$scopedSlots.option ? (
                        this.$scopedSlots.option({ option })
                      ) : (
                        <span>{option.label}</span>
                      )}
                      {this.isSelected(option) && !this.multiple && (
                        <span class="dropdown-selected-icon">✓</span>
                      )}
                      {this.isSelected(option) && this.multiple && (
                        <span class="dropdown-selected-icon">✓</span>
                      )}
                    </li>
                  ))
                )}
              </ul>
            </div>
          )}
        </div>
      );
    }
  };
  
  export default {
    name: 'App',
    components: {
      CustomSelect
    },
    data() {
      return {
        // 基础单选数据
        selectedValue: '',
        options: [
          { value: 'option1', label: '选项1' },
          { value: 'option2', label: '选项2' },
          { value: 'option3', label: '选项3' },
          { value: 'option4', label: '选项4' },
          { value: 'option5', label: '选项5' }
        ],
        
        // 多选数据
        multiSelected: [],
        
        // 远程搜索数据
        remoteSelected: '',
        remoteOptions: [],
        allRemoteOptions: [
          { value: 'remote1', label: '远程选项1' },
          { value: 'remote2', label: '远程选项2' },
          { value: 'remote3', label: '远程选项3' },
          { value: 'remote4', label: '远程选项4' },
          { value: 'remote5', label: '远程选项5' },
          { value: 'apple', label: '苹果' },
          { value: 'banana', label: '香蕉' },
          { value: 'orange', label: '橙子' }
        ],
        
        // 自定义模板数据
        templateSelected: '',
        templateOptions: [
          { 
            value: 'user1', 
            label: '张三', 
            name: '张三',
            email: 'zhangsan@example.com',
            avatar: 'https://randomuser.me/api/portraits/men/1.jpg'
          },
          { 
            value: 'user2', 
            label: '李四',
            name: '李四',
            email: 'lisi@example.com',
            avatar: 'https://randomuser.me/api/portraits/women/2.jpg'
          },
          { 
            value: 'user3', 
            label: '王五',
            name: '王五',
            email: 'wangwu@example.com',
            avatar: 'https://randomuser.me/api/portraits/men/3.jpg'
          }
        ],
        
        // 可清空数据
        clearableSelected: '',
        
        // 禁用状态
        disabled: false
      };
    },
    methods: {
      // 远程搜索方法
      remoteSearch(query, callback) {
        setTimeout(() => {
          if (!query) {
            callback(this.allRemoteOptions);
          } else {
            const filtered = this.allRemoteOptions.filter(option => 
              option.label.toLowerCase().includes(query.toLowerCase())
            );
            callback(filtered);
          }
        }, 500);
      },
      // 清空所有选择
      clearAll() {
        this.selectedValue = '';
        this.multiSelected = [];
        this.remoteSelected = '';
        this.templateSelected = '';
        this.clearableSelected = '';
      }
    }
  };
  </script>
  
  <style>
  /* 基础样式 */
  body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 20px;
    background-color: #f5f5f5;
  }
  
  .container {
    max-width: 800px;
    margin: 0 auto;
    background-color: white;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  }
  
  .section {
    margin-bottom: 30px;
    padding-bottom: 20px;
    border-bottom: 1px solid #eee;
  }
  
  h1 {
    color: #333;
    text-align: center;
  }
  
  h2 {
    color: #444;
    margin-top: 0;
  }
  
  .controls {
    margin-bottom: 10px;
  }
  
  button {
    padding: 5px 10px;
    margin-right: 10px;
    background-color: #4CAF50;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
  }
  
  button:hover {
    background-color: #45a049;
  }
  
  /* 下拉框样式 */
  .dropdown {
    position: relative;
    display: inline-block;
    width: 100%;
    max-width: 300px;
    font-size: 14px;
  }
  
  .dropdown-toggle {
    position: relative;
    padding: 8px 30px 8px 12px;
    border: 1px solid #ddd;
    border-radius: 4px;
    background-color: white;
    cursor: pointer;
    user-select: none;
    min-height: 36px;
    display: flex;
    align-items: center;
  }
  
  .dropdown-toggle:hover {
    border-color: #aaa;
  }
  
  .dropdown-selection {
    flex-grow: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: #555;
  }
  
  .dropdown-arrow {
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    color: #999;
    font-size: 12px;
  }
  
  .dropdown-clear {
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    color: #999;
    font-size: 16px;
    cursor: pointer;
  }
  
  .dropdown-clear:hover {
    color: #333;
  }
  
  .dropdown-menu {
    position: absolute;
    top: 100%;
    left: 0;
    width: 100%;
    margin-top: 4px;
    border: 1px solid #ddd;
    border-radius: 4px;
    background-color: white;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    z-index: 1000;
    max-height: 250px;
    overflow-y: auto;
  }
  
  .dropdown-search {
    padding: 8px;
    border-bottom: 1px solid #eee;
  }
  
  .search-input {
    width: 100%;
    padding: 6px 10px;
    border: 1px solid #ddd;
    border-radius: 4px;
    outline: none;
  }
  
  .search-input:focus {
    border-color: #aaa;
  }
  
  .dropdown-options {
    list-style: none;
    padding: 0;
    margin: 0;
  }
  
  .dropdown-option {
    padding: 8px 12px;
    cursor: pointer;
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  
  .dropdown-option:hover {
    background-color: #f5f5f5;
  }
  
  .dropdown-option.is-selected {
    background-color: #f0f7ff;
    color: #1a73e8;
  }
  
  .dropdown-option.is-disabled {
    color: #ccc;
    cursor: not-allowed;
  }
  
  .dropdown-selected-icon {
    color: #1a73e8;
    font-weight: bold;
  }
  
  .dropdown-loading, .dropdown-empty {
    padding: 8px 12px;
    color: #999;
    text-align: center;
  }
  
  .is-disabled .dropdown-toggle {
    background-color: #f5f5f5;
    cursor: not-allowed;
    color: #aaa;
  }
  
  /* 自定义选项样式 */
  .custom-option {
    display: flex;
    align-items: center;
    width: 100%;
  }
  
  .avatar {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    margin-right: 10px;
  }
  
  .info {
    display: flex;
    flex-direction: column;
  }
  
  .name {
    font-weight: bold;
  }
  
  .email {
    font-size: 12px;
    color: #777;
  }
  </style>